import logging
from modbus_tk.modbus_tcp import TcpServer


class DPModbusServer:
    def __init__(self, port, ip='0.0.0.0'):
        self.ip = ip
        self.port = port
        self.server = TcpServer(address=self.ip, port=self.port)
        self.slave = None

    def init_address_space(self, slave_id: int, block_list):
        """
        :param slave_id:
        :param block_list:
        :return:
        """
        self.slave = self.server.add_slave(slave_id)
        if self.slave:
            for item in block_list:
                self.slave.add_block(item[0], item[1], item[2], item[3])

    def start(self):
        self.server.start()

    def stop(self):
        if self.server:
            self.server.stop()


def background_process(data: dict):
    uuid = data.get('uuid')
    ip = data.get('host')
    port = int(data.get('port'))
    block_name = f'block_name_{uuid}'
    dp_mod_server = DPModbusServer(port, ip)
    block_type_result = []
    blcok_type_list = [data.get('coils'), data.get('discrete_inputs'), data.get('hoding_register'),
                       data.get('analog_inputs')]
    for index, block_type in enumerate(blcok_type_list, start=1):
        if block_type == 'true':
            block_type_result.append([block_name, int(index), int(data.get(f'start_address_{index}')),
                                      int(data.get(f'quantity_{index}'))])
    try:
        slave_id = int(data.get('slave_id'))
        dp_mod_server.init_address_space(slave_id, block_type_result)
        dp_mod_server.start()
    except Exception as e:
        print(e)
        if dp_mod_server:
            dp_mod_server.stop()


def main():
    dpmd = DPModbusServer(502, '0.0.0.0')
    try:
        dpmd.init_address_space(1, [['test_block', 3, 0, 100]])
        dpmd.start()
        logging.info('modbus server start at: port 502. listenning....')
    except Exception as e:
        print(e)
        logging.error(str(e))
        dpmd.stop()

'''
def check_redis():
    try:
        _redis_client = request.redis_client
    except AttributeError:
        redis_client = Redis(host=REDIS['HOST'], port=REDIS['PORT'], db=REDIS['DB'])
        request.redis_client = redis_client
    _redis_client = request.redis_client
    try:
        _redis_client.ping()
    except ConnectionError:
        if _redis_client:
            _redis_client.close()
        redis_client = Redis(host=REDIS['HOST'], port=REDIS['PORT'], db=REDIS['DB'])
        request.redis_client = redis_client
'''